package com.lean.plugin

import com.google.gson.reflect.TypeToken
import com.lean.plugin.network.AdInfo
import com.lean.plugin.network.ApiResponse
import com.lean.plugin.network.GsonFactory
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.internal.EMPTY_REQUEST
import okhttp3.logging.HttpLoggingInterceptor
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.IoActions
import org.gradle.internal.enterprise.test.OutputFileProperty
import org.gradle.internal.util.PropertiesUtils
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.nio.charset.Charset
import java.util.*
import java.util.concurrent.TimeUnit

abstract class FetchAdConfigTask : DefaultTask() {

    @get:Input
    abstract val baseUrl: Property<String>

    @get:Input
    abstract val applicationId: Property<String>

    @get:OutputFile
    abstract val destPropertyFile: RegularFileProperty

    private val httpClient by lazy {
        val builder = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS).connectionPool(ConnectionPool(10, 5, TimeUnit.MINUTES))
        builder.addInterceptor(HttpLoggingInterceptor { msg ->
            println(msg)
        }.setLevel(HttpLoggingInterceptor.Level.BODY))
        builder.build()
    }


    @TaskAction
    fun action() {
        //request flavor config.
        val url = baseUrl.get() + "/api/ad_info"
        val request = Request.Builder()
            .url(url)
            .addHeader("Package", applicationId.get())
            .method("POST", EMPTY_REQUEST)
            .build()


        httpClient.newCall(request).execute().use { response ->
            if (!response.isSuccessful) {
                println(response.message)
            } else {
                val responseText = response.body?.string()
                if (responseText.isNullOrEmpty()) {
                    print("response body is empty")
                } else {
                    try {
                        val responseType = object : TypeToken<ApiResponse<AdInfo>>() {}.type
                        val apiResponse = GsonFactory.gson.fromJson<ApiResponse<AdInfo>>(responseText, responseType)
                        if (apiResponse.isSuccessful()) {
                            val adInfo = apiResponse.data
                            val propertyMap = hashMapOf(
                                "appId" to adInfo.appId,
                                "splashId" to adInfo.splashAdId,
                                "interstitialId" to adInfo.interstitialAdId,
                                "feedId" to adInfo.feedAdId,
                                "rewardId" to adInfo.rewardAdId,
                                "privacyAgreementUrl" to adInfo.privacyAgreementUrl,
                                "userAgreementUrl" to adInfo.userAgreementUrl
                            )

                            val charset = Charset.forName("UTF-8")
                            val file: File = destPropertyFile.asFile.get()
                            val out: OutputStream = BufferedOutputStream(FileOutputStream(file))
                            try {
                                val propertiesToWrite = Properties()
                                propertiesToWrite.putAll(propertyMap)
                                PropertiesUtils.store(propertiesToWrite, out, null, charset, "\n")
                            } finally {
                                IoActions.closeQuietly(out)
                            }

                        } else {
                            println(apiResponse.msg)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }

            }
        }
    }

}